package com.jiguang.shangcheng.servlet;

import com.jiguang.shangcheng.dao.ShangChengDao;
import com.jiguang.shangcheng.pojo.Product;
import com.jiguang.shangcheng.pojo.User;
import lombok.SneakyThrows;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.*;
import java.util.UUID;

import static com.jiguang.shangcheng.servlet.updatePerson.*;

@MultipartConfig
@WebServlet("/shang/shang_upProduct")
public class upProduct extends HttpServlet {
    @SneakyThrows
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置字符集
        resp.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("UTF-8");

        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("name");

        //获取参数
        String name = req.getParameter("name");
        String game = req.getParameter("game");
        String price = req.getParameter("price");
        Part part = req.getPart("file");
        String file = part.getSubmittedFileName();
        if (name == null || game == null || price == null || file == null ||
                name.trim().equals("") || game.trim().equals("") || price.trim().equals("") || file.equals("")) {
            PrintWriter out = resp.getWriter();
            out.println("<script>alert('请将数据填写完整');location.href='/shang/shang_grounding.jsp';</script>");
            out.close();
            return;
        }

        // 创建上传文件的保存路径。建议保存在WEB-INF下，安全，用户无法直接访问上传的文件
        String uploadPath = this.getServletContext().getRealPath("/upload");
        System.out.println("文件保存路径-->" + uploadPath);
        File uploadFile = new File(uploadPath);
        // 如果此文件夹不存在就直接创建一个
        if (!uploadFile.exists()) {
            uploadFile.mkdir();
        }

        // 临时路径,假如文件超过了预期大小，我们就把他放入一个临时文件中
        String tempPath = this.getServletContext().getRealPath("/temp");
        System.out.println("临时文件保存路径-->" + tempPath);
        File tempFile = new File(tempPath);
        if (!tempFile.exists()) {
            tempFile.mkdir();
        }

        // 处理上传的文件，一般需要通过流来获取，我们可以使用request.getInputStream(),原生态的文件上传流获取，十分麻烦
        //但是我们都建议使用Apache的文件上传组件来实现，common-fileupload,他需要依赖commons-io组件


        /**
         *  1.创建DiskFileItemFactory对象：处理文件上传路径或者大小限制的
         */
        DiskFileItemFactory factory = getDiskFileItemFactory(tempFile);

        /**
         * 2.获取ServletFileUpload
         * ServletFileUpload负责处理上传的文件数据，并将表单中每个输入项封装成一个FileItem对象
         * 在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象
         * 所以，我们需要在进行解析工作前构造好DiskFileItemFactory对象
         *通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性
         */
        ServletFileUpload upload = getServletFileUpload(factory);

        /**
         *  3.处理上传的文件
         */

        String fileName = null;
        try {
            fileName = uploadParseRequest(upload, req, uploadPath);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }

        if(fileName == null || fileName.equals("")){
            PrintWriter out = resp.getWriter();
            out.println("<script>alert('图片文件不符合要求');location.href='/shang/shang_grounding.jsp';</script>");
            out.close();
        }

        //添加商品
        Product product = new Product();
        product.setName(name);
        product.setGame(game);
        product.setPrice(price);
        product.setPhoto(fileName);
        product.setUserId(user.getId());
        ShangChengDao shangChengDao = new ShangChengDao();
        boolean result = shangChengDao.insertProdutc(product);

        if(result){
            PrintWriter out = resp.getWriter();
            out.println("<script>alert('上架成功');location.href='/shang/shang_index';</script>");
            out.close();
        }else{
            PrintWriter out = resp.getWriter();
            out.println("<script>alert('上架失败');location.href='/shang/shang_grounding.jsp';</script>");
            out.close();
        }
    }

    public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 监听上传进度
        upload.setProgressListener(new ProgressListener() {
            @Override
            // pBytesRead:已经读到的大小
            // pContentLength:文件大小
            public void update(long pBytesRead, long pContentLength, int i) {
                System.out.println("总大小：" + pContentLength + "已经上传：" + pBytesRead);
            }
        });
        // 处理乱码
        upload.setHeaderEncoding("UTF-8");
        // 设置单个文件的最大值
        upload.setFileSizeMax(1024 * 1024 * 10);
        // 设置总共能够上传文件的大小
        upload.setSizeMax(1024 * 1024 * 10);
        return upload;
    }

    public static DiskFileItemFactory getDiskFileItemFactory(File tempFile) {
        // 通过该工厂设置一个缓冲区，当上传文件大于缓冲区时，将他放到临时文件中
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 设置缓冲区大小为10M
        factory.setSizeThreshold(1024 * 1024 * 10);
        // 临时目录的保存目录
        factory.setRepository(tempFile);
        return factory;
    }

    public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath)
            throws FileUploadException, IOException, ServletException {
        String fileName = "";
        // =======================处理文件===============================//

        // 拿到文件名字
        Part part = request.getPart("file");
        String uploadFileName = part.getSubmittedFileName();
        System.out.println("上传的文件名：" + uploadFileName);


        // 获得上传的文件名 /images/girl/paojie.png
        fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
        // 获得文件的后缀名
        String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
        if(!(fileExtName.equals("jpg") || fileExtName.equals("JPG") || fileExtName.equals("PNG") || fileExtName.equals("png") || fileExtName.equals("GIF") || fileExtName.equals("gif") ||
                fileExtName.equals("TIF") || fileExtName.equals("tif"))){
            return null;
        }
        /*
         * 如果文件后缀名 fileExtName 不是我们所需要的 就直接return，不处理，告诉用户文件类型不对。
         */

        System.out.println("文件信息 [件名：" + fileName + "---文件类型" + fileExtName + "]");

        // 可以使用UUID（唯一识别的通用码），保证文件名唯一；
        // UUID.randomUUID()，随机生一个唯一识别的通用码；
        String uuidPath = UUID.randomUUID().toString();

        // =======================处理文件完毕===============================//

        // 存到哪？ uploadPath
        // 文件真实存在的路径 realPath
        String realPath = uploadPath + "/" + uuidPath;
        // 给每个文件创建一个对应的文件夹
        File realPathFile = new File(realPath);
        if (!realPathFile.exists()) {
            realPathFile.mkdir();
        }

        // =======================存放地址完毕===============================//

        // 获得文件上传的流
        InputStream inputStream = part.getInputStream();

        // 创建一个文件输出流
        // realPath = 真实的文件夹；
        // 差了一个文件; 加上输出文件的名字+"/"+uuidFileName
        FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);

        // 创建一个缓冲区
        byte[] buffer = new byte[1024 * 1024];

        // 判断是否读取完毕
        int len = 0;
        // 如果大于0说明还存在数据；
        while ((len = inputStream.read(buffer)) > 0) {
            fos.write(buffer, 0, len);
        }

        // 关闭流
        fos.close();
        inputStream.close();

        // =======================文件传输完毕===============================//
        return uuidPath + "/" + fileName;
    }

}
